package com.storm.lib.net.socket.codec;

import java.util.zip.InflaterInputStream;
import java.io.DataInputStream;
import java.io.UnsupportedEncodingException;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Input;
import flex.messaging.io.amf.ASObject;


import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.omg.CORBA.portable.RemarshalException;

import com.storm.lib.util.ByteUtil;


/**
 * 
 * 类功能:数据解码器
 * 数据包结构：数据头+数据体
 * @author johnny
 * @version 2011-8-9
 */
public class AMF3Decoder extends CumulativeProtocolDecoder {
	/**
	 * 总计的解码数量
	 */
	//public static int totalDecoder=0;
	private final SerializationContext context = new SerializationContext();
//	private final Amf3Input amf3in;
	
//	public AMF3Decoder() {
//		amf3in = new Amf3Input(context);
//	}	

	private final AttributeKey POLICY = new AttributeKey(getClass(), "policy");
	private final String security = "<policy-file-request/>";

	/**
	 * 解码
	 */
	protected boolean doDecode(IoSession session, IoBuffer in,ProtocolDecoderOutput out) throws Exception {
//		System.out.println("解析请求");
		if (isSecurityRequest(session, in)) {
			//in.get(new byte[in.limit()]);
			in.get();
			out.write(security);
			//in.free();
			return true;
		} else {
		
			//设定当前的指针
			Amf3Input amf3in = new Amf3Input(context);
			int originalPosition=in.position();
			if(in.remaining()>4){
		        in.mark();//标记当前位置,以便reset 
		        //第一位是数据头数据,标记了后面数据体的长度
		        int size = in.getInt();
		        //如果消息内容不够，则重置，相当于不读取size
		        if(size > in.remaining()){//  
	                in.reset();
	                //接收新数据，以拼凑成完整数据   
	                return false;
		        }
		        else{
		        	//判断是否出现粘包
		        	if(size<in.remaining()){
	//	        		System.out.println("---------------------------------------------");
						amf3in.setInputStream(new InflaterInputStream(new DataInputStream(in.asInputStream())));			
						Object message = amf3in.readObject();
						out.write(message);	   				
		        		in.position(originalPosition+4+size);
		        		return true;
		        	}
		        	//正常情况
		        	else{
						amf3in.setInputStream(new InflaterInputStream(new DataInputStream(in.asInputStream())));			
						Object message = amf3in.readObject();
						out.write(message);	        		
		        	}
		        }
			}
			return false;
		}
	}
	
	private boolean isSecurityRequest(IoSession session, IoBuffer in) {
		Boolean policy = (Boolean) session.getAttribute(POLICY);
		if (policy != null) {
			return false;
		}
		String request = getRequest(in);
		boolean result = false;
		if (request != null) {
			result = request.startsWith(security);
		}
		session.setAttribute(POLICY, new Boolean(result));
		return result;
	}

	private String getRequest(IoBuffer in) {
		//byte[] bytes = new byte[in.limit()];
		//in.get(bytes);
		byte[] bytes = in.array();
		String request;
		
		try {
			request = new String(bytes, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			request = null;
		}
		return request;
	}
	
}
